package com.safety360.app.util;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Hashtable;

import android.annotation.SuppressLint;
import android.os.Environment;
import android.util.Log;

public class MyLogger {
	private final static boolean logFlag = true;
	private final static boolean logWriteToFile = true;

	private final static String tag = "360SafeApp";
	private final static int logLevel = Log.VERBOSE;
	private static Hashtable<String, MyLogger> sLoggerTable = new Hashtable<String, MyLogger>();
	private String mClassName;

	public static MyLogger getLogger(String className) {
		MyLogger classLogger = (MyLogger) sLoggerTable.get(className);
		if (classLogger == null) {
			classLogger = new MyLogger(className);
			sLoggerTable.put(className, classLogger);
		}
		return classLogger;
	}

	private MyLogger(String name) {
		mClassName = name;
	}

	private String getFunctionName() {
		StackTraceElement[] sts = Thread.currentThread().getStackTrace();

		if (sts == null) {
			return null;
		}

		for (StackTraceElement st : sts) {

			if (st.isNativeMethod()) {
				continue;
			}

			if (st.getClassName().equals(Thread.class.getName())) {
				continue;
			}

			if (st.getClassName().equals(this.getClass().getName())) {
				continue;
			}

			return "[ " + Thread.currentThread().getName() + ": "
					+ st.getFileName() + ":" + st.getLineNumber() + " ]";
		}
		return null;
	}

	public void i(Object str) {
		if (logFlag) {
			if (logLevel <= Log.INFO) {
				String name = getFunctionName();
				if (name != null) {
					Log.i(tag, name + " - " + str);
					if (logWriteToFile) {
						writeLogToFile(name + " - " + str);
					}
				} else {
					Log.i(tag, str.toString());
					if (logWriteToFile) {
						writeLogToFile(str.toString());
					}
				}
			}
		}

	}

	public void v(Object str) {
		if (logFlag) {
			if (logLevel <= Log.VERBOSE) {
				String name = getFunctionName();
				if (name != null) {
					Log.v(tag, name + " - " + str);
					Log.v(tag, "logWriteToFile" + " : " + logWriteToFile);
					if (logWriteToFile) {
						writeLogToFile(name + " - " + str);
					}
				} else {
					Log.v(tag, str.toString());
					if (logWriteToFile) {
						writeLogToFile(str.toString());
					}
				}
			}
		}
	}

	public void w(Object str) {
		if (logFlag) {
			if (logLevel <= Log.WARN) {
				String name = getFunctionName();
				if (name != null) {
					Log.w(tag, name + " - " + str);
					if (logWriteToFile) {
						writeLogToFile(name + " - " + str);
					}
				} else {
					Log.w(tag, str.toString());
					if (logWriteToFile) {
						writeLogToFile(str.toString());
					}
				}
			}
		}
	}

	public void e(Object str) {
		if (logFlag) {
			if (logLevel <= Log.ERROR) {
				String name = getFunctionName();
				if (name != null) {
					Log.e(tag, name + " - " + str);
					if (logWriteToFile) {
						writeLogToFile(name + " - " + str);
					}
				} else {
					Log.e(tag, str.toString());
					if (logWriteToFile) {
						writeLogToFile(str.toString());
					}
				}
			}
		}
	}

	public void e(Exception ex) {
		if (logFlag) {
			if (logLevel <= Log.ERROR) {
				Log.e(tag, "error", ex);
				if (logWriteToFile) {
					writeLogToFile(ex);
				}
			}
		}
	}

	public void e(String log, Throwable tr) {
		if (logFlag) {
			String line = getFunctionName();
			Log.e(tag, "{Thread:" + Thread.currentThread().getName() + "}"
					+ "[" + mClassName + line + ":] " + log + "\n", tr);
			if (logWriteToFile) {
				writeLogToFile("{Thread:" + Thread.currentThread().getName()
						+ "}" + "[" + mClassName + line + ":] " + log + "\n"
						+ Log.getStackTraceString(tr));
			}
		}
	}

	public void d(Object str) {
		if (logFlag) {
			if (logLevel <= Log.DEBUG) {
				String name = getFunctionName();
				if (name != null) {
					Log.d(tag, name + " - " + str);
					Log.v(tag, "logWriteToFile" + " : " + logWriteToFile);
					if (logWriteToFile) {
						writeLogToFile(name + " - " + str);
					}
				} else {
					Log.d(tag, str.toString());
					if (logWriteToFile) {
						writeLogToFile(str.toString());
					}
				}
			}
		}
	}

	@SuppressLint("SimpleDateFormat")
	private void writeLogToFile(Object str) {
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-mm-dd");
		if (SDCardUtils.isSdcardExist()) {
			File dir = Environment.getExternalStorageDirectory() ;
			File file = new File(dir.getPath() 
					+ File.separator + "360SafeApp" + File.separator + "log");
			if (!file.exists()) {
				file.mkdirs();
			}

			String fileName = file.getAbsolutePath() + File.separator + "log"
					+ sf.format(new Date()) + ".txt";
			File fil = new File(fileName);
			if (!fil.exists()) {
				try {
					fil.createNewFile();
				} catch (Exception e) {
				}
			}

			FileOutputStream fos = null;
			PrintWriter pw = null;
			try {
				fos = new FileOutputStream(fil, true);
				pw = new PrintWriter(fos);
				if (pw != null) {
					pw.print(str + "\r\n");
					pw.flush();
				}
			} catch (Exception e) {
			} finally {
				try {
					if (fos != null) {
						fos.close();
					}
					if (pw != null) {
						pw.close();
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

	}
}
